home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # Name: format.icn
- #
- # Title: Filter to word wrap a range of text
- #
- # Author: Robert J. Alexander
- #
- # Date: December 5, 1989
- #
- ############################################################################
- #
- # Filter to word wrap a range of text.
- #
- # A number of options are available, including full justification (see
- # usage text, below). All lines that have the same indentation as the
- # first line (or same comment leading character format if -c option)
- # are wrapped. Other lines are left as is.
- #
- # This program is useful in conjunction with editors that can invoke
- # filters on a range of selected text.
- #
- # The -c option attemps to establish the form of a comment based on the
- # first line, then does its best to deal properly with the following
- # lines. The types of comment lines that are handled are those in
- # which each line starts with a "comment" character string (possibly
- # preceded by spaces). While formatting comment lines, text lines
- # following the prototype line that don't match the prototype but are
- # flush with the left margin are also formatted as comments. This
- # feature simplifies initially entering lengthy comments or making
- # major modifications, since new text can be entered without concern
- # for comment formatting, which will be done automatically later.
- #
- ############################################################################
- #
- # Links: options
- #
- ############################################################################
-
- link options
-
- global width
-
- procedure main(arg)
- local usage, opts, tabs, comment, format, just1, space, nspace, wchar
- local line, pre, empty, outline, spaces, word, len
- #
- # Process the options.
- #
- usage :=
- "usage: ifmt [-n] [-w N] [-t N]\n_
- \t-w N\tspecify line width (default 72)\n_
- \t-t N\tspecify tab width (default 8)\n_
- \t-j\tfully justify lines\n_
- \t-J\tfully justify last line\n_
- \t-c\tattemp to format program comments\n_
- \t-h\tprint help message"
- opts := options(arg,"ht+w+cjJ")
- if \opts["h"] then stop(usage)
- width := \opts["w"] | 72
- tabs := \opts["t"] | 8
- comment := opts["c"]
- format := if \opts["j"] then justify else 1
- just1 := opts["J"]
- #
- # Initialize variables.
- #
- space := ' \t'
- nspace := ~space
- wchar := nspace
- #
- # Read the first line to establish a prototype of comment format
- # if -c option, or of leading spaces if normal formatting.
- #
- line := ((tabs >= 2,detab) | 1)(read(),tabs) | exit()
- line ?
- pre := (tab(many(space)) | "") ||
- if \comment then
- tab(many(nspace)) || tab(many(space)) |
- stop("### Can't establish comment pattern")
- else
- ""
- width -:= *pre
- empty := trim(pre)
- outline := spaces := ""
- repeat {
- line ? {
- #
- # If this line indicates a formatting break...
- #
- if (=empty & pos(0)) | (=pre & any(space) | pos(0)) |
- (/comment & not match(pre)) then {
- write(pre,"" ~== outline)
- outline := spaces := ""
- write(line)
- }
- #
- # Otherwise continue formatting.
- #
- else {
- =pre
- tab(0) ? {
- tab(many(space))
- while word := tab(many(wchar)) & (tab(many(space)) | "") do {
- if *outline + *spaces + *word > width then {
- write(pre,"" ~== format(outline))
- outline := spaces := ""
- }
- outline ||:= spaces || word
- spaces := if any('.:?!',word[-1]) then " " else " "
- }
- }
- }
- }
- line := ((tabs >= 2,detab) | 1)(read(),tabs) | break
- }
- write(((tabs >= 2,entab) | 1)(pre,tabs),
- "" ~== (if \just1 then justify else 1)(outline))
- end
-
- #
- # justify() -- add spaces between words until the line length = "width".
- #
- procedure justify(s)
- local min, spaces, len
-
- while *s < width do {
- min := 10000
- s ? {
- while tab(find(" ")) do {
- len := *tab(many(' '))
- if min >:= len then spaces := []
- if len = min then put(spaces,&pos)
- }
- }
- if /spaces then break
- s[?spaces+:0] := " "
- }
- return s
- end
-